package com.media.service.listener.record;

import com.media.cache.CacheUtil;
import com.media.common.Constants;
import com.media.common.ffmpeg.FFmpegError;
import com.media.common.ffmpeg.FFmpegUtil;
import com.media.config.MediaCaptorLiveConfig;
import com.media.pojo.CameraPojo;
import com.media.pojo.ResourceModel;
import com.media.service.listener.HandlerResourceListener;
import com.media.service.listener.RecordResourceListener;
import com.media.utils.DateUtils;
import com.media.utils.ToolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Optional;

/**
 * RTSP 转换视频
 */
@Slf4j
@Service("rtspVideoRecordService")
public class RtspVideoRecordService implements RecordResourceListener {

    @Resource
    MediaCaptorLiveConfig mediaCaptorLiveConfig;


    @Override
    @Async("recordExecutor")
    public void record(ResourceModel resourceModel, HandlerResourceListener handlerListener) {
//     1 : 取出摄像头对象
        CameraPojo cameraPojo = resourceModel.getCameraPojo();
//     2 :取出当前时间戳,作为视频的名称
        long timeMillis = System.currentTimeMillis();
//     3 : 获取到RTSP地址
        String rtsp = FFmpegUtil.getRtsp(
                cameraPojo.getUsername(),
                cameraPojo.getPassword(),
                cameraPojo.getIp(),
                cameraPojo.getChannel(),
                cameraPojo.getStream());
//     4 : 视频要保存的路径  /home/resources/#{id}/video/2024-11-28/3412342342134.mp4
        String videoPath = mediaCaptorLiveConfig.getResourcesSavePath() + "/" +
                cameraPojo.getId() + "/" +
                Constants.VIDEO + "/" +
                DateUtils.getDate() + "/";
//     5 : 创建文件夹 / 删除上一个录制视频的进程
        ToolUtils.mkdirs(videoPath);
        CacheUtil.closeVideoMap(String.valueOf(cameraPojo.getId()));
        String videoFile = videoPath + timeMillis + Constants.MP4;
        List<String> commend = FFmpegUtil.rtspToMp4(rtsp, videoFile, 3600 + "");
//     6 : 开始录制视频
        try {
            InputStream inputStream;
            BufferedReader input;
            ProcessBuilder processBuilder = new ProcessBuilder(commend);
            processBuilder.redirectErrorStream(true);
//        6.1 : 录制之前 , 先把上一个关闭
            CacheUtil.closeVideoMap(String.valueOf(cameraPojo.getId()));
            Process start = processBuilder.start();
//        6.2 : 获取到当前录制视频的进程,保存起来(便于关闭)
            WeakReference<Process> processWeakReference = new WeakReference<>(start);
            CacheUtil.putVideoMap(String.valueOf(cameraPojo.getId()), processWeakReference, timeMillis);
//        6.3 : 录制视频
            inputStream = start.getInputStream();
            input = new BufferedReader(new InputStreamReader(inputStream));
            String line = null;
            while ((line = input.readLine()) != null) {
                log.debug("ffmpeg input={}", line);
                for (String e : FFmpegError.getErrors()) {
                    if (Optional.of(line).filter(r -> r.contains(e)).isPresent()) {
                        log.debug("ffmpeg mp4 error={}", line);
                    }
                }
            }
        } catch (Exception e) {
            log.error("录制视频 , 出现错误 : {}", resourceModel, e);
        } finally {
//            关闭摄像头当前的推流(录制完成/出现错误 : 关闭)
            CacheUtil.closeVideoMap(String.valueOf(cameraPojo.getId()));
        }
        File file = new File(videoFile);
        if (file.exists()) {
            log.info("视频录制成功!! : {}", videoFile);
        }
//      处理视频
        if (handlerListener != null) {
            handlerListener.handler(resourceModel);
        }
    }
}
